package dmitrygusev.ratings.services;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import dmitrygusev.nanoxml.SimpleXPathService;
import dmitrygusev.nanoxml.lite.XMLElement;
import dmitrygusev.ratings.model.Movie;
import dmitrygusev.ratings.model.Rating;

public class KinokopilkaSource extends AbstractSource {
   
	public static final Pattern KINOKOPILKA_MAIN_RATING_PATTERN = Pattern.compile("(\\d+(?:\\.\\d+)?)/\\d.*\\((\\d+)\\)");
	public static final Pattern KINOKOPILKA_IMDB_RATING_PATTERN = Pattern.compile("IMDB:</a>[^\\d]*(\\d+(?:\\.\\d+)?)");
	public static final Pattern KINOKOPILKA_YEAR_PATTERN = Pattern.compile("Дата выпуска:.*(\\d{2}).*(\\d{4})г");
	public static final Pattern KINOKOPILKA_COMMENTS_COUNT_PATTERN = Pattern.compile("все комментарии \\((\\d+)\\)");
	public static final Pattern KINOKOPILKA_COVER_PATTERN = Pattern.compile("main-pic[^s]*src=\"([^\"]*)\"");

	@Override
	public void fetchRawMovies(String query, List<Movie> result) {
		try {
			String html = queryHttp("http://www.kinokopilka.ru/search?search_mode=movies&q="
					+ URLEncoder.encode(query, "UTF-8"), "UTF-8", false);
			
			if (html != null) {
				result.addAll(parseKinokopilkaHTMLResponse(html, query));
			}
		}
		catch (UnsupportedEncodingException e) {
			logger.error(e);
		}
	}

	public List<Movie> parseKinokopilkaHTMLResponse(String html, String query) {
		List<Movie> result = new ArrayList<Movie>();
		
		String magicString = "<div class=\"bg-color noborder\">";
		
		int idx = html.indexOf(magicString);
		while (idx > 0) {
			html = html.substring(0, idx) + "<div>" + html.substring(idx);
			break;
		}

		html = html.replaceAll("border=\"0\"></noscript>", "border=\"0\"/></noscript>");
		html = html.replaceAll("border=\"0\"></a>", "border=\"0\"/></a>");
		
		XMLElement xhtml = new XMLElement();
		xhtml.parseString(html);
		
		List<XMLElement> movies = 
			SimpleXPathService.query(xhtml, "//div[@class='movie']");
		
		for (XMLElement movie : movies) {
			extractKinokopilkaRating(movie, query, result);
		}
		
		return result;
	}

	private void extractKinokopilkaRating(XMLElement movieXml, String query, List<Movie> result) {
		Movie movie = new Movie();
		
		XMLElement titleATag = SimpleXPathService.query(movieXml, 
				"div/span[@class='title']/a").get(0);
		
		String movieHref = titleATag.getAttribute("href").toString();
		
		movie.setCode(movieHref.substring(movieHref.indexOf("/", 1) + 1));
		
		movie.setTitle(titleATag.getContent());

		movie.setUrl("http://www.kinokopilka.ru" + movieHref);

		movie.setTitle2(movieXml.find("//img").get(0).getAttribute("alt").toString());
		
		result.add(movie);
	}

	@Override
	protected void fetchMovieDetails(Movie movie) {
		String movieDetailsHtml = queryHttp(movie.getUrl(), "UTF-8", false);
		
		if (movieDetailsHtml != null) {
			Matcher m = KINOKOPILKA_YEAR_PATTERN.matcher(movieDetailsHtml);
			
			if (m.find()) {
				movie.setYear(m.group(2));
			}
			
			Matcher m2 = KINOKOPILKA_MAIN_RATING_PATTERN.matcher(movieDetailsHtml);
			
			if (m2.find()) {
				Rating value = new Rating();
				value.setType("main");
				value.setValue(m2.group(1));
				value.setVotes(m2.group(2));
				
				movie.addRating(value);
			}
			
			Matcher m3 = KINOKOPILKA_IMDB_RATING_PATTERN.matcher(movieDetailsHtml);
			
			if (m3.find()) {
				Rating value = new Rating();
				value.setType("IMDB");
				value.setValue(m3.group(1));
				value.setVotes("?");
				
				if (! value.getValue().equals("2")) {
					movie.addRating(value);
				}
			}
			
			Matcher m4 = KINOKOPILKA_COMMENTS_COUNT_PATTERN.matcher(movieDetailsHtml);
			
			if (m4.find()) {
				movie.setCommentsCount(m4.group(1));
			} else {
				movie.setCommentsCount("0");
			}
			
			Matcher m5 = KINOKOPILKA_COVER_PATTERN.matcher(movieDetailsHtml);
			
			if (m5.find()) {
				movie.setCoverPicture("http://www.kinokopilka.ru" + m5.group(1));
			}
		}
	}

	@Override
	public String getName() {
		return "КиноКопилка.ру";
	}

}
